package com.alks.function.service.impl.stockdept.pcfactorystockquery;

import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.entity.data.entity.PcMtlAcc;
import com.alks.entity.data.entity.PcSlipTemp;
import com.alks.entity.data.entity.PcSurplusDetail;
import com.alks.entity.data.entity.PcSurplusTemp;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.OMtlInDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.OtMtlOutDto;
import com.alks.function.data.request.stockdept.pcfactorystockwork.OMtlwaitAddRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.SurpDetailRequest;
import com.alks.function.mapper.stockdept.pcfactorystockquery.*;
import com.alks.function.service.stockdept.pcfactorystockquery.IMtlToSurpService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.alks.entity.data.enums.ResultCodeEnum.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class MtlToSurpServiceImpl extends ServiceImpl<SD_SQ_PcSurplusDetailMapper, PcSurplusDetail> implements IMtlToSurpService {
    private final SD_SQ_PcSurplusDetailMapper detailMapper;
    private final SD_SQ_PcSurplusTempMapper tempMapper;
    private final SD_SQ_PcLotUsageMapper usageMapper;
    private final SD_SQ_PcMtlAccMapper accMapper;
    private final SD_SQ_SdMaterialMapper materialMapper;
    private final SD_SQ_SdBomPartNew2Mapper partNew2Mapper;
    private final RedisService redisService;


    @Override
    public ResponseInfo getMTSTempQuery() {
        /*获取数据*/
        LambdaQueryWrapper<PcSurplusTemp> wrapper = new LambdaQueryWrapper<PcSurplusTemp>()
                .select(PcSurplusTemp::getLotNo, PcSurplusTemp::getMtlNo, PcSurplusTemp::getMtlColor,
                        PcSurplusTemp::getMtlName, PcSurplusTemp::getQty, PcSurplusTemp::getRemark)
                .eq(PcSurplusTemp::getSysUser, UserIdThread.get().getLoginName())
                .eq(PcSurplusTemp::getSlipType, "A");
        List<PcSurplusTemp> temps = tempMapper.selectList(wrapper);
        /*提取数据*/
        List<OtMtlOutDto> dtos = BeanUtil.copyList(temps, OtMtlOutDto.class);
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo getMTSDetailQuery(SurpDetailRequest request) {
        /*获取数据*/
        List<PcSurplusDetail> details = lambdaQuery()
                .eq(PcSurplusDetail::getSysUser,UserIdThread.get().getLoginName())
                .eq(PcSurplusDetail::getSlipType,"A")
                .eq(request.getSlipNo() != null && !request.getSlipNo().isEmpty(), PcSurplusDetail::getSlipNo, request.getSlipNo())
                .eq(request.getSlipReason() != null && !request.getSlipReason().isEmpty(), PcSurplusDetail::getSlipReason, request.getSlipReason())
                .ge(request.getSlipDateStart() != null, PcSurplusDetail::getSlipDate, request.getSlipDateStart())
                .le(request.getSlipDateEnd() != null, PcSurplusDetail::getSlipDate, request.getSlipDateEnd()).list();
        /*提取数据*/
        List<OMtlInDto> dtos = BeanUtil.copyList(details, OMtlInDto.class);
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo mTSTempAdd(List<OMtlwaitAddRequest> request, Integer type) {
        /*判断材料是否已存在*/
        List<String> mtlNos = request.stream().map(OMtlwaitAddRequest::getMtlNo).collect(Collectors.toList());
        LambdaQueryWrapper<PcSurplusTemp> wrapper = new LambdaQueryWrapper<PcSurplusTemp>()
                .select(PcSurplusTemp::getMtlName)
                .eq(PcSurplusTemp::getSlipType,"A")
                .eq(PcSurplusTemp::getSysUser,UserIdThread.get().getLoginName())
                .in(PcSurplusTemp::getMtlNo, mtlNos);
        List<PcSurplusTemp> temps = tempMapper.selectList(wrapper);
        if (temps != null && !temps.isEmpty() && temps.get(0).getMtlName() != null) {
            return ResponseInfo.ok("存在重复物料：" + temps.get(0).getMtlName());
        }
        /*获取数据*/
        List<PcSlipTemp> slipTemps = new ArrayList<>();
        switch (type) {
            case 1:
                slipTemps = materialMapper.getOtMtlWaitStk2(request);
                break;
            case 2:
                slipTemps = usageMapper.getOtMtlWaitStk2(request);
                break;
            case 3:
                slipTemps = partNew2Mapper.getOtMtlWaitStk2(request);
                break;
            case 4:
                slipTemps = accMapper.getOtMtlWaitStk2(request);
                break;
        }
        /*判断数据是否存在*/
        if (slipTemps == null || slipTemps.isEmpty()) {
            log.error("请求方法：mTSTempAdd\n错误原因：没有找到数据\n请求参数：mtlNo:{},type:{}",
                    request.get(0).getMtlNo(), type);
            return ResponseInfo.error("数据异常，请重试", DATA_IS_ERR.getCode());
        }
        /*写入数据*/
        tempMapper.mTSTempAdd(slipTemps, UserIdThread.get().getLoginName());
        return ResponseInfo.ok("写入成功");
    }

    @Override
    public ResponseInfo mTSTempUp(String mtlNo, BigDecimal qty, String remark) {
        /*判断库存是否充足*/
        if (qty != null && mtlNo.charAt(0) != 'U' && mtlNo.charAt(0) != 'H') {
            LambdaQueryWrapper<PcMtlAcc> wrapper = new LambdaQueryWrapper<PcMtlAcc>()
                    .select(PcMtlAcc::getStkQty)
                    .eq(PcMtlAcc::getMtlNo, mtlNo)
                    .last("LIMIT 1");
            PcMtlAcc pcMtlAcc = accMapper.selectOne(wrapper);
            if (pcMtlAcc==null||pcMtlAcc.getStkQty().compareTo(qty)<0){
                return ResponseInfo.error("库存量不足");
            }
        }
        /*更新对应数据*/
        tempMapper.mTSTempUp(mtlNo, qty, remark,UserIdThread.get().getLoginName());
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo mTSDetailAdd(String mtlNo, String slipReason, LocalDateTime slipDate) {
        /*获取数据，判断合法性*/
        LambdaQueryWrapper<PcSurplusTemp> wrapper=new LambdaQueryWrapper<PcSurplusTemp>()
                .eq(PcSurplusTemp::getMtlNo,mtlNo)
                .last("LIMIT 1");
        PcSurplusTemp temp = tempMapper.selectOne(wrapper);
        if (temp==null||BeanUtil.allIsEmpty(temp)){
            log.error("请求方法：mTSDetailAdd\n错误原因：没有找到数据\n表：PC_SURPLUS_TEMP\n请求方法：mtlNo:{}",mtlNo);
            return ResponseInfo.error("添加失败，请重试", DATA_IS_EMPTY.getCode());
        }
        if (temp.getQty()==null||temp.getQty()<=0){
            return ResponseInfo.error("数量不能为空", INPUT_ERROR.getCode());
        }
        /*生成订单号*/
        String slipNo = redisService.slipNoCreat("E");
        /*生成写入数据实体类*/
        PcSurplusDetail detail = BeanUtil.copyBean(temp, PcSurplusDetail.class);
        detail.setStockNo("XS");
        detail.setSlipNo(slipNo);
        detail.setSlipReason(slipReason);
        detail.setSlipDate(slipDate);
        detail.setSlipType("A");
        detail.setSysUser(UserIdThread.get().getLoginName());
        detail.setItem(1);
        detail.setSlipDate(LocalDate.now().atStartOfDay());
        detail.setSysDate(LocalDateTime.now());
        /*写入数据*/
        detailMapper.insert(detail);
        /*删除temp表中的数据*/
        LambdaQueryWrapper<PcSurplusTemp> tempWrapper=new LambdaQueryWrapper<PcSurplusTemp>()
                .eq(PcSurplusTemp::getMtlNo,mtlNo)
                .eq(PcSurplusTemp::getSysUser,UserIdThread.get().getLoginName())
                .eq(PcSurplusTemp::getSlipType,"A");
        tempMapper.delete(tempWrapper);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo mTSTempDelete(String mtlNo) {
        /*删除对应数据*/
        LambdaQueryWrapper<PcSurplusTemp> wrapper=new LambdaQueryWrapper<PcSurplusTemp>()
                .eq(PcSurplusTemp::getMtlNo,mtlNo)
                .eq(PcSurplusTemp::getSysUser,UserIdThread.get().getLoginName())
                .eq(PcSurplusTemp::getSlipType,"A")
                .last("LIMIT 1");
        tempMapper.delete(wrapper);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo mTSDetailDelete(String slipNo, String mtlNo) {
        /*删除对应数据*/
        LambdaQueryWrapper<PcSurplusDetail> wrapper=new LambdaQueryWrapper<PcSurplusDetail>()
                .eq(PcSurplusDetail::getMtlNo,mtlNo)
                .eq(PcSurplusDetail::getSlipNo,slipNo)
                .eq(PcSurplusDetail::getSysUser,UserIdThread.get().getLoginName())
                .eq(PcSurplusDetail::getSlipType,"A")
                .last("LIMIT 1");
        detailMapper.delete(wrapper);
        return ResponseInfo.ok();
    }
}
